package csv;

import java.io.FileReader;
import java.io.FileWriter;
import java.util.ArrayList;
import java.util.List;

import parser.IupacParser;
import utils.SystemCommand;
import au.com.bytecode.opencsv.CSVReader;
import au.com.bytecode.opencsv.CSVWriter;

public class CsvTranslator {

	private char delimiter;
	private char quoteChar;
	private String csvExt;
	private String csvDirPath;

	private String fileName;		
	
	private String iupacDirPath;
	private String iupacFileName;
	private String iupacFileExt;
	
	private String glycoctDirPath;
	private String glycoctFileName;
	private String glycoctFileExt;
	
	private String pyScriptName;
	
	private int cfgColIdx;
	private int iupacColIdx;
	private int glycanTypeColIdx;
	
	public CsvTranslator(){
		
	}
	
	public CsvTranslator(char delimiter, char quoteChar, String csvExt, String csvDirPath, String iupacDirPath, String glycoctDirPath, String fileName, String iupacFileName, String iupacFileExt, String glycoctFileName, String glycoctFileExt, String pyScriptName, int cfgColIdx, int iupacColIdx, int glycanTypeColIdx){
		this.setDelimiter(delimiter);
		this.setDelimiter(delimiter);
		this.setQuoteChar(quoteChar);
		this.setCsvExt(csvExt);
		this.setCsvDirPath(csvDirPath);
		this.setIupacDirPath(csvDirPath);
		this.setIupacFileName(iupacFileName);
		this.setIupacFileExt(iupacFileExt);
		
		this.setGlycoctDirPath(csvDirPath);
		this.setGlycoctFileName(glycoctFileName);
		this.setGlycoctFileExt(glycoctFileExt);
		
		this.setFileName(fileName);
		
		
		
		this.setPyScriptName(pyScriptName);
		
		this.setCfgColIdx(cfgColIdx);
		this.setIupacColIdx(iupacColIdx);
		this.setGlycanTypeColIdx(glycanTypeColIdx);
	}
	
	public void translate(){
		try
		{
			String pyArgScript = csvDirPath + pyScriptName + " ";
			String pyArgInFile = csvDirPath + fileName + csvExt + " ";
			String pyArgColIdx = cfgColIdx + " ";
			String pyArgOutFile = csvDirPath + iupacFileName + csvExt;

//			SystemCommand.execute("python " + csvDirPath+pyScriptName + " " + csvDirPath + cfgFileName + " " + cfgColIdx + " " + csvDirPath+iupacFileName);
			SystemCommand.execute("python " + pyArgScript + pyArgInFile + pyArgColIdx + pyArgOutFile);
			
			
			List<String[]> rows = readCsvFile(iupacDirPath + iupacFileName + iupacFileExt, delimiter, quoteChar);
			rows = translateAll(rows, iupacColIdx, glycanTypeColIdx);
			writeCsvFile(glycoctDirPath + glycoctFileName + glycoctFileExt, rows, delimiter, quoteChar);
		}
		catch(Exception ex)
		{
			System.err.println("CsvUpdater main error : " + ex.getMessage());
		}
	}
	
	public static List<String[]> readCsvFile(String filePath, char delimiter, char quoteChar)
	{
		CSVReader reader = null;
		List<String[]> rows = null;
		try
		{
			reader = new CSVReader(new FileReader(filePath), delimiter, quoteChar);
			rows = reader.readAll();
			
			
			for(int i=0 ;i<rows.size();i++)
			{
				String[] row = rows.get(i);
				
//				for(int j=0;j<row.length;j++)
//				{
//					System.out.println("Row "+ i + " " + j +" "+row[j]);
//				}
//				System.out.println("------------");
			}	
		}
		catch (Exception ex) 
		{
			System.err.println("readCsvFile" + ex.getMessage());
		}
		return rows;
	}
	
	
	
	public static List<String[]> writeCsvFile(String filePath, List<String[]> rows, char delimiter, char quoteChar)
	{
		CSVWriter writer = null;
		
		try
		{
			writer = new CSVWriter(new FileWriter(filePath), delimiter, quoteChar);		
		
			for(int i=0 ;i<rows.size();i++)
			{	
				String[] row = rows.get(i);
			
				for(int j=0;j<row.length;j++)
				{
					System.out.println("Row "+ i + " " + j +" "+row[j]);
				}
				System.out.println("------------");
				writer.writeNext(row);
			}
			writer.close();
	    }
		catch (Exception ex) 
		{
			System.err.println("writeCsvFile" + ex.getMessage());
		}
		return rows;
	}
	
	public String translateIupacToGlycoct(String iupac, String glycanType)
	{
		String glycoct = "";
		
		if(iupac!=null && iupac.length()!=0)
		{	
			long begin = System.nanoTime();
			IupacParser p= new IupacParser(iupac);
			p.setGlycanType(glycanType); //N-LINKED (-> beta), O-LINKED (-> alpha)
			
			
			try
			{					
				p.getCtTree(p.parse());
				
//				System.out.println("IUPAC sequence : ");
//				System.out.println(p.getIupacSequence());
//				System.out.println("");
//				System.out.println("CT sequence : ");
				glycoct = p.getCtSequence();
//				System.out.println(glycoct);					
			}
			catch(Exception ex)
			{
				System.err.println("Problem parsing the sequence");
				ex.printStackTrace();
			}
			long end = System.nanoTime();				
			System.out.println("");
			System.out.println("Process time [s] : " + (end-begin)*Math.pow(10, -9));
		}
		return glycoct;		
	}		

	
	public List<String[]> translateAll(List<String[]> rows, int iupacColIdx, int glycanTypeColIdx)
	{
		ArrayList<String[]> newRows = new ArrayList<String[]>();
		
		for(int i=0 ;i<rows.size();i++)
		{	
			String[] row = rows.get(i);
			String glycanType ="";
			
			if(glycanTypeColIdx>0)
			{
				glycanType = row[glycanTypeColIdx];
			}
			
			String glycoct = translateIupacToGlycoct(row[iupacColIdx], glycanType);
//			System.out.println("row length : " + row.length);
			System.out.println(glycoct);
			
			String[] newRow = new String[row.length+1];
			for (int j=0;j<row.length;j++)
			{
				newRow[j]=row[j];
			}
			newRow[row.length]=glycoct;
			newRows.add(newRow);
			
		}	
		return newRows;		
	}



	public char getDelimiter() {
		return delimiter;
	}



	public void setDelimiter(char delimiter) {
		this.delimiter = delimiter;
	}



	public char getQuoteChar() {
		return quoteChar;
	}



	public void setQuoteChar(char quoteChar) {
		this.quoteChar = quoteChar;
	}



	public String getCsvExt() {
		return csvExt;
	}



	public void setCsvExt(String csvExt) {
		this.csvExt = csvExt;
	}



	public String getCsvDirPath() {
		return csvDirPath;
	}



	public void setCsvDirPath(String csvDirPath) {
		this.csvDirPath = csvDirPath;
	}



	public String getIupacDirPath() {
		return iupacDirPath;
	}



	public void setIupacDirPath(String iupacDirPath) {
		this.iupacDirPath = iupacDirPath;
	}



	public String getGlycoctDirPath() {
		return glycoctDirPath;
	}



	public void setGlycoctDirPath(String glycoctDirPath) {
		this.glycoctDirPath = glycoctDirPath;
	}



	public String getFileName() {
		return fileName;
	}



	public void setFileName(String fileName) {
		this.fileName = fileName;
	}



	public String getIupacFileName() {
		return iupacFileName;
	}



	public void setIupacFileName(String iupacFileName) {
		this.iupacFileName = iupacFileName;
	}



	public String getGlycoctFileName() {
		return glycoctFileName;
	}



	public void setGlycoctFileName(String glycoctFileName) {
		this.glycoctFileName = glycoctFileName;
	}



	public String getPyScriptName() {
		return pyScriptName;
	}



	public void setPyScriptName(String pyScriptName) {
		this.pyScriptName = pyScriptName;
	}



	public int getCfgColIdx() {
		return cfgColIdx;
	}



	public void setCfgColIdx(int cfgColIdx) {
		this.cfgColIdx = cfgColIdx;
	}



	public int getIupacColIdx() {
		return iupacColIdx;
	}



	public void setIupacColIdx(int iupacColIdx) {
		this.iupacColIdx = iupacColIdx;
	}



	public int getGlycanTypeColIdx() {
		return glycanTypeColIdx;
	}



	public void setGlycanTypeColIdx(int glycanTypeColIdx) {
		this.glycanTypeColIdx = glycanTypeColIdx;
	}

	public String getIupacFileExt() {
		return iupacFileExt;
	}

	public void setIupacFileExt(String iupacFileExt) {
		this.iupacFileExt = iupacFileExt;
	}

	public String getGlycoctFileExt() {
		return glycoctFileExt;
	}

	public void setGlycoctFileExt(String glycoctFileExt) {
		this.glycoctFileExt = glycoctFileExt;
	}
}
